package com.ce.pms.charge.service.impl;


import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.ce.pms.base.service.impl.PmsBaseServiceImpl;
import com.ce.pms.charge.dao.IChargeVoucherDao;
import com.ce.pms.charge.dao.IPeriodDao;
import com.ce.pms.charge.dao.ITransactionDao;
import com.ce.pms.charge.model.VoucherDomain;
import com.ce.pms.charge.service.IAccountService;
import com.ce.pms.charge.service.IBankAccountService;
import com.ce.pms.charge.service.IChargeVoucherService;
import com.ce.pms.charge.service.IMeterDataRegisterService;
import com.ce.pms.charge.vo.BankAccountVO;
import com.ce.pms.charge.vo.ChargeVoucherSearchVO;
import com.ce.pms.charge.vo.ChargeVoucherVO;
import com.ce.pms.charge.vo.OriginalMeterDataVO;
import com.ce.pms.charge.vo.VoucherPayMethodVO;
import com.ce.pms.common.dao.IOrganizationalStructureDao;
import com.ce.pms.common.dao.ISecUserDao;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.customer.dao.IClientRHouseDao;
import com.ce.pms.customer.model.ParticipantDO;
import com.ce.pms.customer.service.ICustomerService;
import com.ce.pms.customer.vo.ProRightVO;
import com.ce.pms.house.model.HouseDomain;
import com.ce.pms.house.service.IHouseService;
import com.ce.pms.report.vo.ChargeVoucherReportVO;
import com.ce.pms.report.vo.ChargeVoucherSubVO;
import com.ce.util.BlankUtil;
import com.ce.util.RmbUtil;
import com.sitechasia.webx.core.support.Page;

/**
 *
 * 功能描述：收费凭证打印
 * <p>版权所有：中企动力
 * <p>未经本公司许可，不得以任何方式复制或使用本程序任何部分
 *
 * @author 黄彦军 Created on 2008-8-15 Edit author: Edit on: 修改原因:
 */
public class ChargeVoucherServiceImpl extends PmsBaseServiceImpl implements
		IChargeVoucherService {


	private IChargeVoucherDao chargeVoucherDao;

	private IPeriodDao periodDao;

	private ICustomerService customerService;

	private ITransactionDao transactionDao;

	private IHouseService houseService;

	private IMeterDataRegisterService meterDataRegisterService;

	private IAccountService accountService;

	private IBankAccountService bankAccountService;

	private ISecUserDao secUserDao;

	private IClientRHouseDao clientRHouseDao;

	public void setClientRHouseDao(IClientRHouseDao clientRHouseDao) {
		this.clientRHouseDao = clientRHouseDao;
	}

	public IAccountService getAccountService() {
		return accountService;
	}

	public void setAccountService(IAccountService accountService) {
		this.accountService = accountService;
	}


	public IHouseService getHouseService() {
		return houseService;
	}


	/**
	 * @param secUserDao the secUserDao to set
	 */
	public void setSecUserDao(ISecUserDao secUserDao) {
		this.secUserDao = secUserDao;
	}

	public void setHouseService(IHouseService houseService) {
		this.houseService = houseService;
	}

	/**
	 * 功能描述: 查询当前页凭证集合列表 <br>
	 * @param voucherSearchVO 凭证查询条件VO
	 * @return Map 0:当前页数据集合   1:当前页  2:总行数  3:页大小
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-15  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Page queryCurrentlyPageVoucher(ChargeVoucherSearchVO voucherSearchVO) {

		Page page = chargeVoucherDao.queryCurrentlyPageVoucher(voucherSearchVO);

		List<ChargeVoucherVO> list = new ArrayList<ChargeVoucherVO>();

		if (!BlankUtil.isBlank(page.getResult())) {
			List tempList = page.getResult();
			int listSize = tempList.size();
			for (int i = 0; i < listSize; i++) {
				Object[] obj = (Object[]) tempList.get(i);
				ChargeVoucherVO  voucherVO = this.objArrayToVoucherVO(obj);
				String participantName = findClientNamesByHouseIdAndProRightId(voucherVO.getHouseId(),voucherVO.getProRightVO().getProRightId());
				voucherVO.setParticipantName(participantName);
				list.add(voucherVO);
			}
		}
		page.setResult(list);
		return page;
	}

	/**
	 * 功能描述:根据房号及产权号查询业姓名  <br>
	 * @param ClientNames
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-18  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private String findClientNamesByHouseIdAndProRightId(Long houseId,Long proRightId){
		List<ParticipantDO> list = clientRHouseDao.getAllOwnerByHouseId(houseId,proRightId);
		if (BlankUtil.isBlank(list)) {
			return "";
		}
		String clientName = "";

		for (ParticipantDO participantDO : list) {
			clientName += participantDO.getParticipantName()+",";
		}
		if (!BlankUtil.isBlank(clientName))
			clientName = clientName.substring(0,clientName.length()-1);


		return clientName;
	}

//	/**
//	 * 功能描述:根据房号查询业主姓名  <br>
//	 * @param ClientNames
//	 * @return
//	 * Create author:黄彦军 <br>
//	 * Create on:2008-8-18  <br>
//	 * Edit author:  <br>
//	 * Edit on:    <br>
//	 * Why:     <br>
//	 */
//	private String findClientNamesByHouseNumber(String houseNumber){
//
//		List<CustomerHouseVO> customerHouses = customerService.getHouseAndCustomerBy(houseNumber);
//		if (BlankUtil.isBlank(customerHouses) || customerHouses.size() ==0)
//			return "";
//
//		String clientName ="";//业主姓名
//		for (CustomerHouseVO houseVO : customerHouses) {
//			clientName += houseVO.getOwnerName()+",";
//		}
//		if (!BlankUtil.isBlank(clientName))
//		clientName = clientName.substring(0,clientName.length()-1);
//
//		return clientName;
//	}


	/**
	 * 功能描述:将对象数组中的数据封装成一个ChargeVoucherVO <br>
	 * @param objArray
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-15  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private ChargeVoucherVO objArrayToVoucherVO(Object[] objArray) {
		ChargeVoucherVO chargeVoucherVO = new ChargeVoucherVO();

		chargeVoucherVO.setVoucherId(Long.parseLong((objArray[0].toString())));//凭证ID
		chargeVoucherVO.setBuilding(objArray[1] == null ? null:(String)objArray[1]);//楼栋名称
		chargeVoucherVO.setHouseId(objArray[2]==null ?null: Long.parseLong(objArray[2].toString()));//房屋编号ID
		chargeVoucherVO.setHouseNumber(objArray[3] == null ? null:(String)objArray[3]);//房号
		chargeVoucherVO.setPeriod(objArray[4] == null ? null:(String)objArray[4]);//收费周期
		chargeVoucherVO.setVoucherNumber(objArray[5] == null ? null:(String)objArray[5]);//凭证名称
		chargeVoucherVO.setParticipantName(objArray[6] == null ? null:(String)objArray[6]);//业主
		chargeVoucherVO.setChargeDate(objArray[7] == null ? null:(Date)objArray[7]);//收费时间
		chargeVoucherVO.setPayMethod(objArray[8] == null ? null:(String)objArray[8]);//缴费方式
		chargeVoucherVO.setSum(objArray[9] == null ? new BigDecimal(0) :(BigDecimal) objArray[9]);//缴费总金额
		chargeVoucherVO.setStatuz(objArray[10] == null ? null:(String)objArray[10]);//状态

		ProRightVO proRightVO = new ProRightVO();
		proRightVO.setProRightId(objArray[11] == null ? null: Long.valueOf(((BigInteger)objArray[11]).toString()));//产权Id
		chargeVoucherVO.setProRightVO(proRightVO);

		return chargeVoucherVO;
	}

	/**
	 * 功能描述:查询打印总次数  <br>
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-22  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Long findPrintTotal() {
		List list = chargeVoucherDao.findPrintTotal();
		Long total = new Long(0);
		if (!BlankUtil.isBlank(list)) {
			if (!BlankUtil.isBlank(list.get(0))) {
				total = (Long) list.get(0);
			}
		}
		return total;
	}

	/**
	 * 功能描述:打印一个凭证，将打印资料加1,如果状态为新建的，则修改为已打印  <br>
	 * @param voucherID
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-22  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public void updateVoucherStart(Long voucherID){
		VoucherDomain voucherDomain =chargeVoucherDao.findById(voucherID);

		Short printTimes = voucherDomain.getPrintTimes();
		if (BlankUtil.isBlank(printTimes)){
			printTimes = 0;
		}

		int print = (int)printTimes;
		print +=1;
		String statuz =SysrefcodeDO.FEE_VOUCHER_STATUZ_NEW;
		if (statuz.equals((String)voucherDomain.getStatuz())){
			voucherDomain.setStatuz(SysrefcodeDO.FEE_VOUCHER_STATUZ_PRINTED);
		}
		voucherDomain.setPrintTimes(Short.parseShort((print+"").trim()));
	}

	/**
	 * 功能描述:凭证支付明细  <br>
	 * @param obj
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-10-9  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public List getpayTrans(Long voucherID,String sortStr) {
		List<VoucherPayMethodVO> list = new ArrayList<VoucherPayMethodVO>();
		VoucherPayMethodVO payMethodVO = this.getTransByVoucherId(voucherID);
		if (BlankUtil.isBlank(payMethodVO))
			return list;

		List temp = transactionDao.getVoucherSubtransByTransId(payMethodVO.getTransId(),sortStr);
		if (BlankUtil.isBlank(temp) || temp.size() == 0){
			list.add(payMethodVO);
			return list;
		}

		for (int i = 0; i < temp.size(); i++) {
			Object [] obj = (Object[]) temp.get(i);
			payMethodVO = this.payTransToVO(obj);
			list.add(payMethodVO);
		}
		return list;
	}

	/**
	 * 功能描述:根据凭证ID 查找支付列表(支付方式) <br>
	 * @param voucherID
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-10-9  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	@SuppressWarnings("unchecked")
	public List<VoucherPayMethodVO> getPayListByVoucherId(Long voucherID){
		List methods = new ArrayList();
		VoucherPayMethodVO payMethodVO = this.getTransByVoucherId(voucherID);

		if (BlankUtil.isBlank(payMethodVO)) {
			return null;
		}

		List list = transactionDao.getPayListByTransId(payMethodVO.getTransId());
		if (BlankUtil.isBlank(list))
			return null;

		for (int i = 0; i < list.size(); i++) {
			Object[] obj = (Object[]) list.get(i);
			payMethodVO = this.payMehtodToVO(obj);
			methods.add(payMethodVO);
		}
		return methods;
	}

	/**
	 * 功能描述:获取一个凭证的交易摘要  <br>
	 * @param voucherId
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-10-9  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public String getpaySummaryByVoucherId(Long voucherId){
		VoucherPayMethodVO payMethodVO = this.getTransByVoucherId(voucherId);

		return payMethodVO == null ? "" : payMethodVO.getPaySummary();
	}


	/**
	 * 功能描述:获取打印信息  <br>
	 * @param voucherId
	 * @param houseId
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-10-9  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public ChargeVoucherReportVO voucherReport(Long voucherId,Long houseId){
		VoucherDomain voucherDomain = chargeVoucherDao.findById(voucherId);
		HouseDomain house = voucherDomain.getHouse();
		Long proRightId = voucherDomain.getProRight().getProRightId();

		Long createId = voucherDomain.getSysInfo().getCreator();
		String crdateName = secUserDao.queryUserNameById(createId);// 操作人
		VoucherPayMethodVO payMethodVO = this.getTransByVoucherId(voucherId);//主交易信息
		String period =	payMethodVO.getPeriod();
		BankAccountVO bankAccountVO =bankAccountService.getCurrentBankAccount(houseId);

		List payMethods = getPayListByVoucherId(voucherId);
		String payMethod = "";//缴费方式
		for(int i =0;i<payMethods.size();i++){
			VoucherPayMethodVO methodVO = (VoucherPayMethodVO) payMethods.get(i);
			payMethod =payMethod + methodVO.getPayMethod()+ ",";
		}
		payMethod=payMethod.substring(0,payMethod.length()- 1);

		//查询主报表信息
		ChargeVoucherReportVO reportVO = new ChargeVoucherReportVO();
		reportVO.setVoucherDate(period.substring(0,4)+"年"+period.substring(4,6)+"月份"); //头日期

		Date date = voucherDomain.getChargeDate(); // 收费日期
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		reportVO.setCreateDate(format.format(date)); //缴费日期
		reportVO.setParticipantName(this.findClientNamesByHouseIdAndProRightId(house.getKeyword(),proRightId)); //业主
		reportVO.setHouseNumber(house.getHouseNumber());//房号
		reportVO.setBuildSize(house.getBuildSize());//面积
		reportVO.setAccountNumber( bankAccountVO == null ? null :bankAccountVO.getAccNumber());//银行帐号
		reportVO.setPayType(payMethod);//缴费方式
		reportVO.setTotalFactPay(voucherDomain.getSum());//实收费用合计

		BigDecimal sum = voucherDomain.getSum();
		Double summ =  new Double(sum.toString());
		String totalFactPayCase =  RmbUtil.getRMB(summ);
		reportVO.setTotalFactPayCase(totalFactPayCase);//合计 大写
		reportVO.setPayee(crdateName);//收费人

		//查询子报表列表
		List list = chargeVoucherDao.getChanagVoucherInfo(payMethodVO.getTransId());
		List<ChargeVoucherSubVO> subList = new ArrayList<ChargeVoucherSubVO>();
		if (!BlankUtil.isBlank(list)){
			for (int i = 0; i < list.size(); i++) {
				ChargeVoucherSubVO subVO = this.chargeVoucherSubToVO((Object[])list.get(i));
				subList.add(subVO);
			}
		}
		reportVO.setSubList(subList);
		return reportVO;
	}

	/**
	 * 功能描述:凭证明细子报表  <br>
	 * @param obj
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-10-10  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private ChargeVoucherSubVO chargeVoucherSubToVO(Object[] obj){
		ChargeVoucherSubVO subVO = new ChargeVoucherSubVO();
		if (BlankUtil.isBlank(subVO)) return subVO;
		subVO.setPrice(obj[0] == null ? null : (BigDecimal)obj[0]);
		subVO.setChargeItem(obj[1] == null ? null : (String)obj[1]);
		if (obj[4] == null|| "".equals((String)obj[4])){
		subVO.setLastReading(null);
			subVO.setThisReading(null);
			subVO.setDosage(null);
		}else{
			String houseNumber = (String)obj[3];
			String meterType = (String)obj[4];
			OriginalMeterDataVO meterDataVO = meterDataRegisterService.findMeterDataVOByHouseNumber(houseNumber,meterType);
			subVO.setLastReading(meterDataVO.getLastReading());
			subVO.setThisReading(meterDataVO.getThisReading());
			subVO.setDosage(meterDataVO.getWastage());
		}

		return subVO;
	}

	/**
	 * 功能描述:凭证支付明细 ToVO  <br>
	 * @param obj
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-10-9  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private VoucherPayMethodVO payTransToVO(Object[] obj){
		if (BlankUtil.isBlank(obj))
			return null;
		VoucherPayMethodVO payMethodVO = new VoucherPayMethodVO();
		payMethodVO.setTransId(obj[0] == null ? null: new Long(obj[0].toString()));
		payMethodVO.setTransName(obj[1]== null ? null :(String)obj[1]);
		payMethodVO.setPeriod(obj[2] == null ? null : (String)obj[2]);
		payMethodVO.setPrice(obj[3] == null ? new BigDecimal(0): (BigDecimal)obj[3]);
		payMethodVO.setBusinessCodeId(obj[4] == null ? null: new Long(obj[4].toString()));
		payMethodVO.setPayMethod(obj[5] == null ? null : (String)obj[5].toString());
		payMethodVO.setPaySummary(obj[6] == null ? null:(String)obj[6]);
		payMethodVO.setItemName(obj[7] == null? null:(String)obj[7]);
		payMethodVO.setCrdateDate(obj[8] == null ? null :(Date)obj[8]);
		payMethodVO.setPayMethodCode(obj[9] == null ? null :(String)obj[9]);

		return payMethodVO;
	}

	/**
	 * 功能描述:根据凭证 id 查找 主交易信息  <br>
	 * @param voucherId
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-10-9  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private VoucherPayMethodVO getTransByVoucherId(Long voucherId){
		List temp = transactionDao.getTransByVoucherId(voucherId);
		if (BlankUtil.isBlank(temp)) {
			return null;
		}
		Object[] obj = (Object[]) temp.get(0);
		VoucherPayMethodVO payMethodVO = this.payTransToVO(obj);
		return payMethodVO;
	}

	/**
	 * 功能描述:转化交易方式VO  <br>
	 * @param obj
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-10-9  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private VoucherPayMethodVO payMehtodToVO(Object[] obj){
		if (BlankUtil.isBlank(obj))
			return null;
		VoucherPayMethodVO payMethodVO = new VoucherPayMethodVO();
		payMethodVO.setPayments(obj[0] == null ? new BigDecimal(0): (BigDecimal)obj[0]);
		payMethodVO.setPayMethod(obj[1] == null ? null:(String)obj[1]);
		return payMethodVO;
	}

	public IChargeVoucherDao getChargeVoucherDao() {
		return chargeVoucherDao;
	}

	public void setChargeVoucherDao(IChargeVoucherDao chargeVoucherDao) {
		this.chargeVoucherDao = chargeVoucherDao;
	}

	public IPeriodDao getPeriodDao() {
		return periodDao;
	}

	public void setPeriodDao(IPeriodDao periodDao) {
		this.periodDao = periodDao;
	}

	public ICustomerService getCustomerService() {
		return customerService;
	}

	public void setCustomerService(ICustomerService customerService) {
		this.customerService = customerService;
	}

	public ITransactionDao getTransactionDao() {
		return transactionDao;
	}

	public void setTransactionDao(ITransactionDao transactionDao) {
		this.transactionDao = transactionDao;
	}

	public IMeterDataRegisterService getMeterDataRegisterService() {
		return meterDataRegisterService;
	}

	public void setMeterDataRegisterService(
			IMeterDataRegisterService meterDataRegisterService) {
		this.meterDataRegisterService = meterDataRegisterService;
	}

	public IBankAccountService getBankAccountService() {
		return bankAccountService;
	}

	public void setBankAccountService(IBankAccountService bankAccountService) {
		this.bankAccountService = bankAccountService;
	}
}
